{/* Copyright 2020 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License. */}

import {Layout} from '@react-spectrum/docs';
export default Layout;

import docs from 'docs:@react-spectrum/tooltip';
import {HeaderInfo, PropTable, PageDescription} from '@react-spectrum/docs';
import packageData from '@react-spectrum/tooltip/package.json';

```jsx import
import {ActionButton} from '@react-spectrum/button';
import Delete from '@spectrum-icons/workflow/Delete';
import Edit from '@spectrum-icons/workflow/Edit';
import {Flex} from '@react-spectrum/layout';
import Question from '@spectrum-icons/workflow/Question';
import Resize from '@spectrum-icons/workflow/Resize';
import Save from '@spectrum-icons/workflow/SaveTo';
import {Text} from '@react-spectrum/text';
import ThumbUp from '@spectrum-icons/workflow/ThumbUp';
import { Tooltip, TooltipTrigger } from '@react-spectrum/tooltip';
```

---
category: Overlays
keywords: [tooltip]
---

# Tooltip

<PageDescription>{docs.exports.Tooltip.description}</PageDescription>

<HeaderInfo
  packageData={packageData}
  componentNames={['Tooltip, TooltipTrigger']}
  sourceData={[
    {type: 'Spectrum', url: 'https://spectrum.adobe.com/page/tooltip/'}
  ]}
  since="3.4.0" />

## Examples
```tsx example
<TooltipTrigger>
  <ActionButton aria-label="Edit Name"><Edit /></ActionButton>
  <Tooltip>Change Name</Tooltip>
</TooltipTrigger>
```

## Content

The TooltipTrigger accepts exactly two children: the element which triggers the display of the Tooltip and the Tooltip itself. The trigger element must be the first child passed into the TooltipTrigger. All content should be internationalized.

### Accessibility

Tooltip triggers must be focusable and hoverable in order to ensure that all users can activate them. When displayed, TooltipTrigger automatically associates the tooltip with the trigger element so that it is described by the tooltip content.

## Tooltip Delay

Tooltips should appear after a short delay when hovering the trigger, or instantly when using keyboard focus. This delay can be adjusted for hover.
[View guidelines](https://spectrum.adobe.com/page/tooltip/#Immediate-or-delayed-appearance)

```tsx example
<TooltipTrigger delay={0}>
  <ActionButton aria-label="Save"><Save /></ActionButton>
  <Tooltip>Saving applies your new settings right away.</Tooltip>
</TooltipTrigger>
```

### Warmup / Cooldown

Tooltips have a warm up and cool down period, [see guidelines](https://spectrum.adobe.com/page/tooltip/#Warmup-and-cooldown).
Only one tooltip can be open at a time.
```tsx example
<Flex gap="size-200">
  <TooltipTrigger>
    <ActionButton>Hover me</ActionButton>
    <Tooltip>I come up after a delay.</Tooltip>
  </TooltipTrigger>
  <TooltipTrigger>
    <ActionButton>Then hover me</ActionButton>
    <Tooltip>If you did it quickly, I appear immediately.</Tooltip>
  </TooltipTrigger>
</Flex>
```

## Tooltip placement

Tooltips support a variety of placement options.

### Placement

The Tooltip's placement with respect to its trigger element can be adjusted using the `placement`
prop. See the props table [below](#tooltiptrigger-props) for a full list of available placement combinations.

```tsx example
<TooltipTrigger placement="end">
  <ActionButton aria-label="Foo">Placement</ActionButton>
  <Tooltip>In left-to-right, this is on the right. In right-to-left, this is on the left.</Tooltip>
</TooltipTrigger>
```

### Offset and cross offset

The Tooltip's offset with respect to its trigger can be adjusted using the `offset` and
`crossOffset` props. The `offset` prop controls the spacing applied along the main axis between the element and its
trigger whereas the `crossOffset` prop handles the spacing applied along the cross axis.

Below is a tooltip offset by an additional 50px above the trigger.
```tsx example
<TooltipTrigger offset={50}>
  <ActionButton aria-label="Offset from trigger">Offset</ActionButton>
  <Tooltip>This will shift up.</Tooltip>
</TooltipTrigger>
```
Below is a tooltip cross offset by an additional 100px to the right of the trigger.
```tsx example
<TooltipTrigger crossOffset={100} placement="bottom">
  <ActionButton aria-label="Cross Offset from trigger">Cross Offset</ActionButton>
  <Tooltip>This will shift over to the right.</Tooltip>
</TooltipTrigger>
```

## Events

TooltipTrigger accepts an `onOpenChange` handler which is triggered whenever the Tooltip is shown or hidden.

The example below uses `onOpenChange` to update a separate element with the current open state of the
Dialog.

```tsx example
function Example() {
  let [isOpen, setOpen] = React.useState(false);

  return (
    <Flex alignItems="center" gap="size-100">
      <TooltipTrigger isOpen={isOpen} onOpenChange={setOpen}>
        <ActionButton aria-label="Resize"><Resize /></ActionButton>
        <Tooltip>Resize text.</Tooltip>
      </TooltipTrigger>
      <Text>Tooltip is {isOpen ? 'showing' : 'not showing'}</Text>
    </Flex>
  );
}
```

## Props

### TooltipTrigger Props
<PropTable component={docs.exports.TooltipTrigger} links={docs.links} />

### Tooltip Props
<PropTable component={docs.exports.Tooltip} links={docs.links} />

## Visual options
[View guidelines](https://spectrum.adobe.com/page/tooltip/#Table-of-options)

**Positive**
```tsx example
<TooltipTrigger>
  <ActionButton aria-label="Approve"><ThumbUp /></ActionButton>
  <Tooltip variant="positive" showIcon>Approve workflow.</Tooltip>
</TooltipTrigger>
```

**Information**
```tsx example
<TooltipTrigger>
  <ActionButton aria-label="Information"><Question /></ActionButton>
  <Tooltip variant="info" showIcon>More information menu.</Tooltip>
</TooltipTrigger>
```

**Negative**
```tsx example
<TooltipTrigger>
  <ActionButton aria-label="Danger Will Robinson"><Delete /></ActionButton>
  <Tooltip variant="negative" showIcon>Dangerous action.</Tooltip>
</TooltipTrigger>
```

## Options
A TooltipTrigger can be disabled without disabling the trigger it displays on.

**isDisabled**
```tsx example
<TooltipTrigger isDisabled>
  <ActionButton aria-label="Danger Will Robinson" onPress={() => alert('pressed trigger')}><Delete /></ActionButton>
  <Tooltip variant="negative" showIcon>Dangerous action.</Tooltip>
</TooltipTrigger>
```

## Usage on disabled or non-interactive elements

Tooltips need to be accessible to keyboard and screen reader users, so we ensure that they are only placed on focusable and hoverable elements. For example, plain text and disabled buttons aren't focusable, meaning keyboard and screen reader users would be unable to access the information in that tooltip.

If you need to display some additional context, consider using [ContextualHelp](ContextualHelp.html).

```tsx example
import {ContextualHelp, Flex, Heading, Content} from '@adobe/react-spectrum';

<Flex gap="size-100" alignItems="center">
  <TooltipTrigger>
    <ActionButton isDisabled>Delete resource</ActionButton>
    <Tooltip variant="negative" showIcon>Dangerous action.</Tooltip>
  </TooltipTrigger>
  <ContextualHelp variant="info">
      <Heading>Permission required</Heading>
      <Content>Your admin must grant you permission before you can delete resources.</Content>
  </ContextualHelp>
</Flex>
```

## Testing

The TooltipTrigger features an popover that transitions in and out of the page as it is opened and closed. It also has a warmup and cooldown
time that you've have to account for when interacting with it. Please see the following sections in the testing docs for more information on how to handle these behaviors in your test suite.

[Timers](./testing.html#timers)

Please also refer to [React Spectrum's test suite](https://github.com/adobe/react-spectrum/blob/main/packages/%40react-spectrum/tooltip/test/TooltipTrigger.test.js) if you find that the above
isn't sufficient when resolving issues in your own test cases.
